/* --------------------------------------

A3_DemandSystemEstimation.do

by: Kristy A.E. Jansen

This do-file: Demand System regressions Jansen (2024) -- part 2
	1. Figure 4+IA1
	2. Figure IA7
	3. Table IA4
	4. Table 6+7+IA7+IA8
	5. Table A1+A2
	6. Table A3

-------------------------------------- */

/* Initialization */
clear all
set more off
capture log clear _all

global root "/Users/kjansen/Desktop/JMP/RFS_replication" // *** NEED TO CHANGE THIS TO CORRECT FILE PATH ***
global main_data $root/DataAnalysis

/* Stata Packages */
*ssc install estout
*ssc install ftools
*ssc install reghdfe

/* Load Data */
use "$root/Data/pseudo_data_part2.dta", clear

/* -------------- Sum Stats ---------------- */
display("Figure 4: Weights of investor types within maturity buckets") // same code to create Figure IA1
preserve
keep if inrange(yq, tq(2011q1), tq(2012q1))
duplicates drop
drop if frac_EU_group_mat_bucket == .
local groups "PF_NL IC_NL MFI MF PFIC_nonNL Other"

foreach group in `groups' {
    display("`group'")
    tabstat frac_EU_group_mat_bucket if group == "`group'", by(mat_bucket) stat(mean)
}
restore

preserve
keep if inrange(yq, tq(2012q3), tq(2013q3))
drop if frac_EU_group_mat_bucket == .

foreach group in `groups' {
    display("`group'")
    tabstat frac_EU_group_mat_bucket if group == "`group'", by(mat_bucket) stat(mean)
}
restore

display("Figure IA7: Maturity structure Dutch debt pre and post UFR")
preserve
keep yq mat_bucket frac_AUM_outs_mat_bucket dummyUFR
duplicates drop
tabstat frac_AUM_outs_mat_bucket if yq < tq(2012q3) , by(mat_bucket) stat(mean median max min)
tabstat frac_AUM_outs_mat_bucket if yq >= tq(2012q3) , by(mat_bucket) stat(mean median max min)
restore

display("Table IA4: Summary statistics demand system") 
sum av_YTM av_dur_bonds  av_convex_bonds  av_coupon AUM_outst_mat_bucket  yield10_DE

/* -------------- Regressions -------------- */
estimates clear
drop if group == "IC_NL" | group == "PF_NL" // Demand system only for other sectors absorbing NL P&I shocks


/*  Foreign sector */
preserve
keep if group == "MFI" // foreign sector only taken once

keep mat_bucket yq foreign_sec_KY2 av_YTM  av_coupon av_dur_bonds* av_convex_bonds* *instr* AUM_outst_mat_bucket ///
 foreign_sec initial_holdings_foreign yield10_DE av_YTM_diff av_YTM_DEFR

xtset mat_bucket yq
sort mat_bucket yq

*First stage 
qui: reg av_YTM instrument av_dur_bonds  av_convex_bonds  av_coupon AUM_outst_mat_bucket /// 
yield10_DE initial_holdings_foreign, vce(cluster yq) 
estimates store first1

*IV
qui: ivregress 2sls foreign_sec_KY2 (av_YTM=instrument) ///
av_dur_bonds  av_convex_bonds  av_coupon AUM_outst_mat_bucket yield10_DE initial_holdings_foreign, vce(cluster yq) 
estimates store model_main1 

g price_elas_foreign_main=1+100*_b[av_YTM]/(av_dur_bonds_alt)*(1-foreign_sec)

*IV with substitute portfolio
qui: ivregress 2sls foreign_sec_KY2 (av_YTM_diff av_YTM_DEFR =  diff_instr instr_cross) ///
av_dur_bonds  av_convex_bonds  av_coupon AUM_outst_mat_bucket yield10_DE initial_holdings_foreign, vce(cluster yq) 
estimates store model_subt1

g price_elas_foreign_subt=1+100*_b[av_YTM_diff]/(av_dur_bonds_alt)*(1-foreign_sec)

*IV with inertia
sort mat_bucket yq
qui: ivregress 2sls foreign_sec_KY2  (av_YTM=instrument) L.foreign_sec_KY2 ///
av_dur_bonds  av_convex_bonds  av_coupon AUM_outst_mat_bucket yield10_DE initial_holdings_foreign, vce(cluster yq) 
estimates store model_alt1

g theta_foreign = 1 - _b[L.foreign_sec_KY2]
g price_elas_foreign_ST = 1+100*_b[av_YTM]/(av_dur_bonds_alt)*(1-foreign_sec)
g price_elas_foreign_LT = price_elas_foreign_ST/theta_foreign

keep mat_bucket yq price_elas_foreign* theta_foreign
tempfile elas_foreign
save `elas_foreign'

restore

/* Euro Area Sectors */
local sector_groups "MFI MF PFIC_nonNL Other"

foreach sector in `sector_groups' {
    preserve
    keep if group == "`sector'"
    keep mat_bucket yq weight port_weight_KY2 av_YTM *instr* av_dur_bonds* av_coupon av_convex_bonds* ///
        AUM_outst_mat_bucket yield10_DE initial_holdings av_YTM_diff av_YTM_DEFR  
    xtset mat_bucket yq
    sort mat_bucket yq

    * First stage
    qui: reg av_YTM instrument av_dur_bonds av_convex_bonds av_coupon AUM_outst_mat_bucket yield10_DE initial_holdings, vce(cluster yq)
    estimates store first`sector'

    * IV main model
    qui: ivregress 2sls port_weight_KY2 (av_YTM = instrument) av_dur_bonds av_convex_bonds av_coupon AUM_outst_mat_bucket ///
	yield10_DE initial_holdings, vce(cluster yq)
    estimates store model_main`sector'

    gen price_elas_`sector'_main = 1 + 100 * (_b[av_YTM] / av_dur_bonds_alt) * (1 - weight)

    * IV with substitute portfolio
    qui: ivregress 2sls port_weight_KY2 (av_YTM_diff av_YTM_DEFR = diff_instr instr_cross) av_dur_bonds av_convex_bonds ///
	av_coupon AUM_outst_mat_bucket yield10_DE initial_holdings, vce(cluster yq)
    estimates store model_subt`sector'

    gen price_elas_`sector'_subt = 1 + 100 * _b[av_YTM_diff] / (av_dur_bonds_alt) * (1 - weight)

    * IV with inertia
    qui: ivregress 2sls port_weight_KY2 (av_YTM = instrument) L.port_weight_KY2 av_dur_bonds av_convex_bonds ///
	av_coupon AUM_outst_mat_bucket yield10_DE initial_holdings, vce(cluster yq)
    estimates store model_alt`sector'

    gen theta_`sector' = 1 - _b[L.port_weight_KY2]
    gen price_elas_`sector'_ST = 1 + 100 * _b[av_YTM] / (av_dur_bonds_alt) * (1 - weight)
    gen price_elas_`sector'_LT = price_elas_`sector'_ST / theta_`sector'

    keep yq mat_bucket price_elas_`sector'* theta_`sector'
    tempfile elas_`sector'
    save `elas_`sector''
    restore
}



/* Merge price elasticities */
keep mat_bucket yq
duplicates drop
qui: merge 1:1 mat_bucket yq using `elas_foreign', keep(master match) nogen
foreach sector in `sector_groups' {
    qui: merge 1:1 mat_bucket yq using `elas_`sector'', keep(master match) nogen
}

/* ------ Results -------- */

display("Panel A Table 6: Demand system - regulatory reform as instrument") // same code to produce Table IA7 using instrument_alt
esttab first*,  ar2(4) b(4) t(2) star(* 0.10 ** 0.05 *** 0.01) ///
varwidth (30) mlabels("Foreign" "Banks" "MFs" "PFIC_nonNL" "Other") nogaps brackets

display("Panel B Table 6: Demand system - regulatory reform as instrument") // same code to produce Table IA7 using instrument_alt
esttab model_main*, ar2(4) b(4) t(2) star(* 0.10 ** 0.05 *** 0.01) ///
varwidth (30) mlabels("Foreign" "Banks" "MFs" "PFIC_nonNL" "Other") nogaps brackets

display("Table A1: Demand system - controlling for a substitute portfolio") 
esttab model_subt*, ar2(4) b(4) t(2) star(* 0.10 ** 0.05 *** 0.01) ///
varwidth (30) mlabels("Foreign" "Banks" "MFs" "PFIC_nonNL" "Other") nogaps brackets

display("Table 7: Price elasticity of demand") // same code to produce Table IA8 using instrument_alt

order price_elas_MFI_main price_elas_foreign_main price_elas_MF_main price_elas_PFIC_nonNL_main price_elas_Other_main
tabstat price_elas*_main, stat(N median sd p5 p95) col(stat) varwidth(25)

display("Table A2: Price elasticity of demand - controlling for a substitute portfolio")
order price_elas_MFI_subt price_elas_foreign_subt price_elas_MF_subt price_elas_PFIC_nonNL_subt price_elas_Other_subt
tabstat price_elas*_subt, stat(N median sd p5 p95)  col(stat) varwidth(25)

display("Table A3: Price elasticity of demand - short-term versus long-term")
order theta_MFI theta_foreign theta_MF theta_PFIC_nonNL theta_Other ///
price_elas_MFI_ST price_elas_foreign_ST price_elas_MF_ST price_elas_PFIC_nonNL_ST price_elas_Other_ST ///
price_elas_MFI_LT price_elas_foreign_LT price_elas_MF_LT price_elas_PFIC_nonNL_LT price_elas_Other_LT

display("Theta")
tabstat theta* , stat(N median) col(stat) varwidth(25)
display("Short-term")
tabstat price_elas*_ST , stat(N median) col(stat) varwidth(25)
display("Long-term")
tabstat price_elas*_LT , stat(N median) col(stat) varwidth(25)


